package org.loon.framework.android.game.core.graphics.component;

import org.loon.framework.android.game.action.sprite.Animation;
import org.loon.framework.android.game.core.LSystem;
import org.loon.framework.android.game.core.graphics.LColor;
import org.loon.framework.android.game.core.graphics.LComponent;
import org.loon.framework.android.game.core.graphics.LContainer;
import org.loon.framework.android.game.core.graphics.LFont;
import org.loon.framework.android.game.core.graphics.opengl.GLEx;
import org.loon.framework.android.game.core.graphics.opengl.LTexture;
import org.loon.framework.android.game.core.graphics.opengl.LTextures;
import org.loon.framework.android.game.core.graphics.opengl.LTexture.Format;
import org.loon.framework.android.game.core.input.LInputFactory.Key;

/**
 * Copyright 2008 - 2009
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
/**
 * LMessage 是LGame 引擎提供的原生组件之一（纯绘制），被用来以逐字打印的方式显示
 * 我们需要的文本信息给用户获悉，并且允许add任意组件到此组件当中。此外，如果我们将它
 * 的setLocked方法设定为False（默认为True），则可以利用触摸屏随意拖拽该组件到屏幕随意
 * 位置。
 * @project loonframework
 * @author chenpeng
 * @email：ceponline@yahoo.com.cn
 * @version 0.1
 */
public class LMessage extends LContainer {

	private Animation animation;

	private LFont messageFont = LFont.getDefaultFont();

	private LColor fontColor = LColor.white;

	private long printTime, totalDuration;

	private int dx, dy, dw, dh;

	private Print print;

	public LMessage(int width, int height) {
		this(0, 0, width, height);
	}

	public LMessage(int x, int y, int width, int height) {
		this((LTexture) null, x, y, width, height);
	}

	public LMessage(String fileName, int x, int y) {
		this(LTextures.loadTexture(fileName), x, y);
	}

	public LMessage(LTexture formImage, int x, int y) {
		this(formImage, x, y, formImage.getWidth(), formImage.getHeight());
	}

	public LMessage(LTexture formImage, int x, int y, int width, int height) {
		super(x, y, width, height);
		this.animation = new Animation();
		if (formImage == null) {
			this.setBackground(new LTexture(width, height, true, Format.SPEED));
			this.setAlpha(0.3F);
		} else {
			this.setBackground(formImage);
			if (width == -1) {
				width = formImage.getWidth();
			}
			if (height == -1) {
				height = formImage.getHeight();
			}
		}
		this.print = new Print(getLocation(), messageFont, width, height);
		this.setTipIcon(LSystem.FRAMEWORK_IMG_NAME + "creese.png");
		this.totalDuration = 80;
		this.customRendering = true;
		this.setWait(false);
		this.setElastic(true);
		this.setLocked(true);
		this.setLayer(100);
	}

	public void setWait(boolean flag) {
		print.setWait(flag);
	}

	public boolean isWait() {
		return print.isWait();
	}

	/**
	 * 强制完成逐字打印效果。在我们不需要LMessage逐字打
	 * 印指定信息时，可以调用此函数直接显示全部数据给用
	 * 户。
	 */
	public void complete() {
		print.complete();
	}

	/**
	 * 设定自消息框左侧起的文本偏移值。（默认为0）
	 * @param left
	 */
	public void setLeftOffset(int left) {
		print.setLeftOffset(left);
	}

	/**
	 * 设定自消息框顶端起的文本偏移值。（默认为0）
	 * @param top
	 */
	public void setTopOffset(int top) {
		print.setTopOffset(top);
	}

	/**
	 * 返回自消息框左侧起的文本偏移值。
	 * @return
	 */
	public int getLeftOffset() {
		return print.getLeftOffset();
	}

	/**
	 * 返回自消息框顶端起的文本偏移值。
	 * @return
	 */
	public int getTopOffset() {
		return print.getTopOffset();
	}

	/**
	 * 返回消息框每行所允许的字符数量。
	 * @return
	 */
	public int getMessageLength() {
		return print.getMessageLength();
	}

	/**
	 * 设定消息框每行所允许的字符数量，当超过此数量时，文
	 * 本打印将自动换行。（在文本中穿插\n符号可提前换行）
	 * @param messageLength
	 */
	public void setMessageLength(int messageLength) {
		print.setMessageLength(messageLength);
	}

	/**
	 * 设定指定路径对应的图片资源为文字悬停时的后缀显示
	 * 图。
	 * @param fileName
	 */
	public void setTipIcon(String fileName) {
		print.setCreeseIcon(new LTexture(fileName));
	}

	/**
	 * 设定指定图片资源为文字悬停时的后缀显示图。
	 * @param icon
	 */
	public void setTipIcon(LTexture icon) {
		print.setCreeseIcon(icon);
	}

	/**
	 * 清空图文字悬停时的后缀显示图。
	 */
	public void setNotTipIcon() {
		print.setCreeseIcon(null);
	}

	public void setEnglish(boolean e) {
		print.setEnglish(true);
	}

	public boolean isEnglish() {
		return print.isEnglish();
	}

	/**
	 * 设定逐字打印时的文字间隔时间。
	 * @param delay
	 */
	public void setDelay(long delay) {
		this.totalDuration = (delay < 1 ? 1 : delay);
	}

	/**
	 * 获取逐字打印时的文字间隔时间。
	 * @return
	 */
	public long getDelay() {
		return totalDuration;
	}

	/**
	 * 判断当前消息框的所有内容是否已经逐字打印完毕。
	 * @return
	 */
	public boolean isComplete() {
		return print.isComplete();
	}

	/**
	 * 设定当前消息框打印完毕时的停止时动画显示位置，该位
	 * 置不能超出消息框所在。
	 * @param dx
	 * @param dy
	 */
	public void setPauseIconAnimationLocation(int dx, int dy) {
		this.dx = dx;
		this.dy = dy;
	}

	/**
	 * 设定消息框的显示内容，当isComplete为True时，将取
	 * 消逐字打印效果。
	 * @param context
	 * @param isComplete
	 */
	public void setMessage(String context, boolean isComplete) {
		print.setMessage(context, messageFont, isComplete);
	}

	/**
	 * 设定消息框的显示内容。
	 * @param context
	 */
	public void setMessage(String context) {
		print.setMessage(context, messageFont);
	}

	public String getMessage() {
		return print.getMessage();
	}

	/**
	 * 处理点击事件（请重载实现）
	 * 当于触摸屏之上点击或释放当前消息框时，将触发此事
	 * 件，可以通过重载此函数完成相应操作。
	 */
	public void doClick() {
		if (Click != null) {
			Click.DownClick(this,input.getTouchX(), input.getTouchY());
			Click.UpClick(this,input.getTouchX(), input.getTouchY());
		}
	}

	protected void processTouchClicked() {
		this.doClick();
	}

	protected void processKeyPressed() {
		if (this.isSelected() && this.input.getKeyPressed() == Key.ENTER) {
			this.doClick();
		}
	}

	/**
	 * 变更当前消息框时间点。
	 * @see org.loon.framework.android.game.core.graphics.LContainer#update(long)
	 */
	public void update(long elapsedTime) {
		if (!visible) {
			return;
		}
		super.update(elapsedTime);
		if (print.isComplete()) {
			animation.update(elapsedTime);
		}
		printTime += elapsedTime;
		if (printTime >= totalDuration) {
			printTime = printTime % totalDuration;
			print.next();
		}
	}

	protected synchronized void createCustomUI(GLEx g, int x, int y, int w,
			int h) {
		if (!visible) {
			return;
		}
		LFont oldFont = g.getFont();
		g.setFont(messageFont);
		print.draw(g, fontColor);
		g.setFont(oldFont);
		if (print.isComplete() && animation != null) {
			if (animation.getSpriteImage() != null) {
				g.setAlpha(1.0F);
				updateIcon();
				g.drawTexture(animation.getSpriteImage(), dx, dy);
			}
		}
		g.resetColor();
	}

	protected void processTouchDragged() {
		if (!locked) {
			if (getContainer() != null) {
				getContainer().sendToFront(this);
			}
			this.move(this.input.getTouchDX(), this.input.getTouchDY());
			this.updateIcon();
		}
	}

	/**
	 * 设定当前消息框打印完毕时的停止时动画。（默认为无，
	 * 可以用来显示一些诸如翻书之类的小动画）
	 * @param animation
	 */
	public void setPauseIconAnimation(Animation animation) {
		this.animation = animation;
		if (animation != null) {
			LTexture image = animation.getSpriteImage(0);
			if (image != null) {
				this.dw = image.getWidth();
				this.dh = image.getHeight();
				this.updateIcon();
			}
		}
	}

	private void updateIcon() {
		this.setPauseIconAnimationLocation(getScreenX() + getWidth() - dw / 2
				- 20, getScreenY() + getHeight() - dh - 10);
	}

	/**
	 * 返回当前文字颜色。
	 * @return
	 */
	public LColor getFontColor() {
		return fontColor;
	}

	/**
	 * 设定当前消息框文字颜色。（也可以通过“<r 文字/>”方
	 * 式输入字符串以改变单个文字颜色）
	 * @param fontColor
	 */
	public void setFontColor(LColor fontColor) {
		this.fontColor = fontColor;
	}

	/**
	 * 返回当前消息框文字字体。
	 * @return
	 */
	public LFont getMessageFont() {
		return messageFont;
	}

	/**
	 * 设定当前消息框文字字体。
	 * @param messageFont
	 */
	public void setMessageFont(LFont messageFont) {
		this.messageFont = messageFont;
	}

	/**
	 * 判断是否锁定了当前消息框。
	 * @return
	 */
	public boolean isLocked() {
		return locked;
	}

	/**
	 * 设定是否锁定当前消息框，默认为True，当为False时消
	 * 息框可以自由拖拽。
	 * @param locked
	 */
	public void setLocked(boolean locked) {
		this.locked = locked;
	}

	protected void validateSize() {
		super.validateSize();
	}

	public void createUI(GLEx g, int x, int y, LComponent component,
			LTexture[] buttonImage) {

	}

	public void setVisible(boolean v) {
		super.setVisible(v);
	}

	public String getUIName() {
		return "Message";
	}

	public void dispose() {
		super.dispose();
		if (print != null) {
			print.dispose();
			print = null;
		}
		if (animation != null) {
			animation.dispose();
			animation = null;
		}
	}
}
